<template>
  <div class="calendar-wrapper" :data-attr="isHideSideBar" v-cloak>
    <header class="calendar-header" v-if="isCanEdit">
      <div class="setting">
        <el-radio class="radio" v-model="curSettingModal" label="freely">自由设置</el-radio>
        <el-radio class="radio" v-model="curSettingModal" label="weekly">按周设置</el-radio>
        <el-radio class="radio" v-model="curSettingModal" label="monthly">按月设置</el-radio>
        <el-radio class="radio" v-model="curSettingModal" label="fullMonthly">整月设置</el-radio>
      </div>
      <div class="header-title">
        <span class="switch-icon last-year-arrow el-icon-arrow-left" @click="switchYear('-')"></span>
        <h3 class="year">{{ curYear }}</h3>
        <span class="switch-icon next-year-arrow el-icon-arrow-right" @click="switchYear('+')"></span>
      </div>
      <div class="operation">
        <a href="javascrip:;" class="ake_btn ake_btn_green" @click.stop="saveCalendar">保存</a>
      </div>
    </header>

    <section class="calendar-body">
      <ul class="calendar-box">
        <li v-for="i in 12" :key="i" class="month-box">
          <month
            ref="oneMonth"
            :year="curYear"
            :month="i - 1"
            :setting-mode="curSettingModal"
            :isLimited="isLimited"
            :disabledStatus="disabledStatus"
            :limitInfo="judgetIsDisabledMonth(i - 1)"
            @dispatchAllMonth="dispatchAllMonth"
          ></month>
        </li>
      </ul>
    </section>

    <!-- 
    调用方式
    <calendar :selectedDate="customDate" :min="" :max="" @save="saveCalendar"></calendar>
    -->
  </div>
</template>

<script>
import { mapGetters } from "vuex";
import Month from "./Month";
import { count, formatTen, deepCopyObj } from "../../assets/js/help.js";
export default {
  data() {
    return {
      curYear: Number(this.year),
      curSettingModal: this.settingMode,
      isLimited: false,
      minDate: [],
      maxDate: []
    };
  },
  props: {
    // 年份
    year: {
      type: [Number, String],
      default: new Date().getFullYear()
    },
    // 默认设置模式
    settingMode: {
      type: String,
      default: "freely"
    },
    // 已经有选择的日期数组
    selectedDate: {
      type: [String, Array]
    },
    // 最小日期
    min: {
      type: [String, Date]
    },
    // 最大日期
    max: {
      type: [String, Date]
    },
    // 是否可编辑
    isCanEdit: {
      type: Boolean,
      default: true
    },
    // 是否不可点击
    disabledStatus: {
      type: Boolean,
      default: false
    }
  },
  components: {
    Month
  },
  computed: {
    ...mapGetters({
      isHideSideBar: "getIsHideSideBar"
    })
  },
  created() {
    if (this.min || this.max) {
      this.isLimited = true;
    } else {
      this.isLimited = false;
    }
    if (this.isLimited) {
      this.getMinDate();
      this.getMaxDate();
    }
    this.setSelectedData(this.selectedDate);
  },
  methods: {
    // 初始拆分日期的结构为 {'年':{'1月': [1,2,3], '2月'： [1,2,3]}}
    // 把年月日拆分是为了好操作每一个月 的数据
    setSelectedData(dateList) {
      if (dateList !== undefined) {
        let resObj = {};
        if (typeof dateList == "string") {
          dateList = dateList ? dateList.split(",") : [];
        }
        for (let i = 0, len = dateList.length; i < len; i++) {
          let _dateArr = dateList[i].split("-"),
            y = _dateArr[0],
            m = Number(_dateArr[1]),
            d = Number(_dateArr[2]),
            _monthObj = resObj[y] ? resObj[y] : {},
            _dayObj = _monthObj[m] ? _monthObj[m] : [];
          _dayObj.push(d);
          resObj[y] = _monthObj;
          resObj[y][m] = _dayObj;
        }
        localStorage.setItem("calendar", JSON.stringify(resObj));
      }
    },
    //切换年份 flag 为 加一年或者减一年的标志
    switchYear(flag) {
      switch (flag) {
        case "+":
          this.curYear++;
          break;
        case "-":
          this.curYear--;
          break;
        default:
          break;
      }
    },
    // 保存选择的日历
    saveCalendar() {
      let selectCalendar = JSON.parse(localStorage.getItem("calendar")) || {},
        resultArr = [];
      if (count(selectCalendar) > 0) {
        for (let y in selectCalendar) {
          let _mData = selectCalendar[y];
          for (let m in _mData) {
            let _dData = _mData[m].sort(function(a, b) {
              return a - b;
            });
            for (let i = 0, len = _dData.length; i < len; i++) {
              let d = _dData[i];
              let res = y + "-" + formatTen(m) + "-" + formatTen(d);
              resultArr.push(res);
            }
          }
        }
      }
      this.$emit("save", resultArr.join(","));
    },
    //将涉及到每个月的操作分发到每个月
    dispatchAllMonth() {
      let $Months = this.$refs["oneMonth"];
      switch (this.curSettingModal) {
        case "monthly":
          for (let i = 0; i < 12; i++) {
            $Months[i].pickEachByMonthly(arguments[0], arguments[1]);
          }
          break;
        case "weekly":
          for (let i = 0; i < 12; i++) {
            $Months[i].pickEachByWeekly(arguments[0], arguments[1]);
          }
          break;
        default:
          break;
      }
    },
    // 获取最小日期的年,月，日的数组
    getMinDate() {
      if (this.min) {
        let _min = new Date(this.min);
        let y = _min.getFullYear(),
          m = _min.getMonth(),
          d = _min.getDate();
        this.minDate = [y, m, d];
      } else {
        this.isLimited = false;
      }
    },
    // 获取最大日期的年,月，日的数组
    getMaxDate() {
      if (this.max) {
        let _max = new Date(this.max);
        let y = _max.getFullYear(),
          m = _max.getMonth(),
          d = _max.getDate();
        this.maxDate = [y, m, d];
      } else {
        this.maxDate = [];
      }
    },
    // 判断当前日历是否有最小日期限制
    isHasMin() {
      if (this.minDate.length == 3) {
        return true;
      }
      return false;
    },
    // 判断当前是否有最大日期限制
    isHasMax() {
      if (this.maxDate.length == 3) {
        return true;
      }
      return false;
    },
    // 判断当月是否在最小和最大日期之间
    // 返回值： {
    // disabled: true|false|'half' //true为整月都不在范围内，false为整月都在范围内，half为该月有一部分在范围内，
    // min: 在diabeld='half'的情况下，如果min>0,则表示该月日期小于min的不在范围内
    // max: 在diabeld='half'max>0,则表示该月日期大于max的不在范围内
    // }
    judgetIsDisabledMonth(m) {
      if (this.isLimited) {
        // 有最小日期或最大日期限制的情况下
        let thisMonth = m,
          isHasMin = this.isHasMin(),
          isHasMax = this.isHasMax(),
          tYear = this.curYear,
          _minY,
          _minM,
          _minD,
          _maxY,
          _maxM,
          _maxD;

        if (isHasMin || isHasMax) {
          // 有最小日期或最大日期限制的情况下
          let disabled = false,
            _singMin = 0,
            _singMax = 0; //
          if (isHasMin) {
            _minY = this.minDate[0];
            _minM = this.minDate[1];
            _minD = this.minDate[2];
          }
          if (isHasMax) {
            _maxY = this.maxDate[0];
            _maxM = this.maxDate[1];
            _maxD = this.maxDate[2];
          }
          if (tYear < _minY || tYear > _maxY) {
            // 如果该年小于最小日期的年份，或大于最大日期的年份
            disabled = true; // 则该年整年都是不可以选(disabled)的状态
          } else {
            if (isHasMin && tYear == _minY) {
              // 如果该年与最小日期的年份相等
              if (thisMonth < _minM) {
                // 如果当月小于最小日期月份，则该月整月disabled状态
                disabled = true;
              } else {
                if (thisMonth == _minM) {
                  // 若谷当月等于最小日期月份，则该月有部分日期是处于范围内的
                  disabled = "half";
                  _singMin = _minD; //该月有效时间范围最小日期的日子
                  if (isHasMax && tYear == _maxY && thisMonth == _maxM) {
                    // 如果此时最大日期的与当年当月的年月是相等的，则可直接返回该月是在最小日期和最大日期之间，并且找到最小日子和最大日子
                    _singMax = _maxD;
                    return {
                      disabled: disabled,
                      min: _singMin,
                      max: _singMax
                    };
                  }
                }
              }
            }
            if (isHasMax && tYear == _maxY) {
              // 如果该年年份与最大日期的年份相等
              if (thisMonth > _maxM) {
                // 如果当月月份大于最大日期的月份，则该月整月处于disabled的状态
                disabled = true;
              } else {
                if (thisMonth == _maxM) {
                  // 如果当月月份等于最大日期的月份， 则该月有部分处于有效范围内，且最大日子为最大日期的日
                  disabled = "half";
                  _singMax = _maxD;
                }
              }
            }
          }
          return {
            disabled: disabled,
            min: _singMin,
            max: _singMax
          };
        }
      }
      // 无最小日期或最大日期限制的情况下，返回空对象
      return {};
    }
  }
};
</script>

<style lang="less" scoped>
@import "../../assets/less/base/variables.less";
@headerH: 50px;
.calendar-header {
  display: flex;
  align-items: center;
  height: @headerH;
  border-bottom: 1px dashed @blue;
  padding-left: 16px;
  padding-right: 16px;
  .setting,
  .operation,
  .header-title {
    flex: 1;
    height: 100%;
  }
  .setting {
    display: flex;
    justify-content: flex-start;
    align-items: center;
  }
  .operation {
    display: flex;
    justify-content: flex-end;
    align-items: center;
  }
  .header-title {
    display: flex;
    justify-content: center;
    align-items: center;
    .switch-icon {
      display: inline-block;
      width: 20%;
      height: @headerH;
      line-height: @headerH;
      font-size: 18px;
      text-align: center;
      cursor: pointer;
    }
    .year {
      text-align: center;
      flex: 1;
      height: 30px;
      line-height: 30px;
      border: 1px solid @greydd;
      border-radius: 5px;
    }
  }
}
.calendar-body {
  padding: 0px 16px 20px 20px;
  .calendar-box {
    padding: 0;
    margin: 0 -0.5em;
    list-style: none;
    .month-box {
      display: inline-block;
      min-width: 246px;
      width: calc(~"25% - 1em");
      margin: 5px 0.5em 5px;
      vertical-align: top;
    }

    @media screen {
      @media (max-width: 1080px) {
        .month-box {
          width: calc(~"33.3% - 1em");
        }
      }
      @media (max-width: 815px) {
        .month-box {
          width: calc(~"50% - 1em");
        }
      }
      @media (max-width: 550px) {
        .month-box {
          width: calc(~"100% - 1em");
        }
      }
    }
  }
}
.line-group {
  display: flex;
  justify-content: space-between;
}
.month-wrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding-top: 10px;
  // border-bottom: 1px solid @blue;
  + .month-wrapper {
    margin-left: 20px;
  }
}
</style>
